package fx.mine.active.component.music;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.dtflys.forest.Forest;
import fx.mine.active.component.music.api.MusicApi;
import fx.mine.active.util.ParseUtil;
import io.github.palexdev.materialfx.controls.MFXButton;
import io.github.palexdev.materialfx.controls.MFXPaginatedTableView;
import io.github.palexdev.materialfx.controls.MFXTableColumn;
import io.github.palexdev.materialfx.controls.cell.MFXTableRowCell;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import lombok.Data;
import lombok.extern.log4j.Log4j2;

import java.util.List;
import java.util.stream.Collectors;

@Log4j2
public class PlayItemsContent extends MFXPaginatedTableView<PlayItemsContent.PlayItem> {

    public PlayItemsContent() {
        AnchorPane.setTopAnchor(this, 300.0);
        AnchorPane.setLeftAnchor(this, 50.0);
        AnchorPane.setRightAnchor(this, 50.0);
        AnchorPane.setBottomAnchor(this, 45.0);

        ObservableList<MFXTableColumn<PlayItem>> tableColumns = getTableColumns();

        MFXTableColumn<PlayItem> idCol = new MFXTableColumn<>("id");
        idCol.setRowCellFactory(playItem -> new MFXTableRowCell<>(PlayItem::getId));
        tableColumns.add(idCol);

        MFXTableColumn<PlayItem> nameCol = new MFXTableColumn<>("name");
        nameCol.setRowCellFactory(playItem -> new MFXTableRowCell<>(PlayItem::getName));
        nameCol.prefWidth(200);
        nameCol.setMinWidth(200);
        tableColumns.add(nameCol);

        MFXTableColumn<PlayItem> playerCol = new MFXTableColumn<>("player");
        playerCol.setRowCellFactory(playItem -> new MFXTableRowCell<>(PlayItem::getPlayer));
        tableColumns.add(playerCol);

        MFXTableColumn<PlayItem> iconCol = new MFXTableColumn<>("icon");
        iconCol.setRowCellFactory(playItem -> new MFXTableRowCell<>(PlayItem::getIconUrl));
        iconCol.prefWidth(250);
        iconCol.setMinWidth(250);
        iconCol.setRowCellFactory(playItem -> {
            MFXTableRowCell<PlayItem, MFXButton> cell = new MFXTableRowCell<>(PlayItem::getIconUrl);
            cell.setLeadingGraphic(playItem.getIconUrl());
            cell.setText("");
            return cell;
        });
        tableColumns.add(iconCol);
        setRowsPerPage(3);

        getSelectionModel().selectionProperty().addListener(new ChangeListener<>() {
            @Override
            public void changed(ObservableValue<? extends ObservableMap<Integer, PlayItem>> observable, ObservableMap<Integer, PlayItem> oldValue, ObservableMap<Integer, PlayItem> newValue) {
                Platform.runLater(() -> {
                    //播放动作
                    playSong(newValue);
                    //填充歌词
                    PlayItem playItem = (PlayItem) newValue.values().toArray()[0];
                    MusicPane.LyricsContainer lyricsContainer = ((MusicPane) PlayItemsContent.this.getParent()).getLyricsContainer();
                    lyricsContainer.paddingContent(playItem.getId());
                    //歌手信息、歌名信息同步
                    PlayerContainer playerContainer = ((MusicPane) PlayItemsContent.this.getParent()).getPlayerContainer();
                    playerContainer.getPlayerNameWatcher().set(playItem.getPlayer());
                    playerContainer.getSongNameWatcher().set(playItem.getName());
                    playerContainer.getDynPreviewIconUrl().set(playItem.getPicUrl());
                });
            }

            private void playSong(ObservableMap<Integer, PlayItem> newValue) {
                PlayItem playItem = (PlayItem) newValue.values().toArray()[0];
                long songId = playItem.getId();
                MusicApi client = Forest.client(MusicApi.class);
                String songStr = client.song(songId);
                PlayerContainer playerContainer = ((MusicPane) PlayItemsContent.this.getParent()).getPlayerContainer();
                playerContainer.trigger(songStr);
            }
        });

        getStyleClass().add("playItems");
        getStylesheets().add(getClass().getResource("/css/playItems.css").toExternalForm());
    }

    @SuppressWarnings("all")
    public void trigger(String jsonStr) {
        try {
            JSONObject jsonObject = JSON.parseObject(jsonStr);
            List<PlayItem> playItemList = (List<PlayItem>) ((JSONArray) jsonObject.get("songs")).stream()
                    .map(o -> {
                        return ParseUtil.parse(() -> {
                            JSONObject object = (JSONObject) o;
                            var playItem = new PlayItem();
                            playItem.setId(object.getLong("id"));
                            playItem.setName((String) JSONPath.eval(o, "$.name"));
                            playItem.setPlayer((String) JSONPath.eval(o, "$.ar[0].name"));
                            String url = (String) JSONPath.eval(o, "$.al[0].picUrl");
                            if (StrUtil.isNotBlank(url)) {
                                ImageView imageView = new ImageView(url);
                                imageView.setFitWidth(200);
                                imageView.setFitHeight(200);
                                MFXButton mfxButton = new MFXButton("", imageView);
                                mfxButton.setPrefSize(250, 210);
                                playItem.setIconUrl(mfxButton);
                                playItem.setPicUrl(url);
                            }
                            return playItem;
                        });
                    }).collect(Collectors.toList());
            this.getItems().addAll(playItemList);
        } catch (Exception e) {
            log.error("音乐服务不可用", e);
        }
    }


    @Data
    public static class PlayItem {
        private long id;
        private String name;
        private String player;
        private MFXButton iconUrl;
        private String picUrl;
    }

}
